#include "stdafx.h"
#include "MetronomeControl.h"
#include "AudioSampler.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;

MetronomeControl::MetronomeControl(System::Windows::Forms::Form * form, System::Windows::Forms::Label * welcomeLabel,
								   System::Windows::Forms::Button * goToTuner, System::Windows::Forms::Button * goToMetronome)
{
	//create pointers to the menu components
	welcomeLabel_ = welcomeLabel;
	goToTunerButton_ = goToTuner;
	goToMetronomeButton_ = goToMetronome;
	
	//initialize tempo to 120
	tempo_ = 120;
	//initialize metronome to off
	shouldRun_ = false;
	
	//create metronome mode components
	metronomeSettingsLabel_ = new System::Windows::Forms::Label();
	metBackButton_ = new System::Windows::Forms::Button();
	tempoLabel_ = new System::Windows::Forms::Label();
	fasterButton_ = new System::Windows::Forms::Button();
	slowerButton_ = new System::Windows::Forms::Button();
	tempoNumberLabel_ = new System::Windows::Forms::Label();
	tempoBox_ = new System::Windows::Forms::GroupBox();
	startMetronomeButton_ = new System::Windows::Forms::Button();
	tempoBox_->SuspendLayout();
	
	// metronomeSettingsLabel
	metronomeSettingsLabel_->Font = new System::Drawing::Font(S"Arial", 14.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, (System::Byte)0);
	metronomeSettingsLabel_->Location = System::Drawing::Point(166, 56);
	metronomeSettingsLabel_->Name = S"metronomeSettingsLabel_";
	metronomeSettingsLabel_->Size = System::Drawing::Size(260, 40);
	metronomeSettingsLabel_->TabIndex = 0;
	metronomeSettingsLabel_->Text = S"Choose Metronome Settings";
	
	// metBackButton
	metBackButton_->Font = new System::Drawing::Font(S"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, (System::Byte)0);
	metBackButton_->Location = System::Drawing::Point(472, 8);
	metBackButton_->Name = S"metBackButton_";
	metBackButton_->Size = System::Drawing::Size(112, 23);
	metBackButton_->TabIndex = 0;
	metBackButton_->Text = S"Back to Main Menu";
	metBackButton_->Click += new System::EventHandler(this, loadMainMenu);
	
	// tempoLabel
	tempoNumberLabel_->Location = System::Drawing::Point(152, 96);
	tempoNumberLabel_->Name = S"tempoNumberLabel_";
	tempoNumberLabel_->TabIndex = 0;
	tempoNumberLabel_->Text = S"120";
	tempoNumberLabel_->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
	
	// fasterButton
	fasterButton_->Location = System::Drawing::Point(304, 96);
	fasterButton_->Name = S"fasterButton_";
	fasterButton_->TabIndex = 2;
	fasterButton_->Text = S"Faster";
	fasterButton_->Click += new System::EventHandler(this, fastTempo);
	
	// slowerButton
	slowerButton_->Location = System::Drawing::Point(32, 95);
	slowerButton_->Name = S"slowerButton_";
	slowerButton_->Size = System::Drawing::Size(64, 24);
	slowerButton_->TabIndex = 1;
	slowerButton_->Text = S"Slower";
	slowerButton_->Click += new System::EventHandler(this, slowTempo);
	
	// tempoName
	tempoLabel_->Location = System::Drawing::Point(152, 144);
	tempoLabel_->Name = S"tempoLabel_";
	tempoLabel_->TabIndex = 3;
	tempoLabel_->Text = S"Allegro";
	tempoLabel_->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
	
	// tempoBox
	//add tempo components to the box
	tempoBox_->Controls->Add(tempoLabel_);
	tempoBox_->Controls->Add(slowerButton_);
	tempoBox_->Controls->Add(fasterButton_);
	tempoBox_->Controls->Add(tempoNumberLabel_);
	tempoBox_->Font = new System::Drawing::Font(S"Arial", 9.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, (System::Byte)0);
	tempoBox_->Location = System::Drawing::Point(104, 128);
	tempoBox_->Name = S"tempoBox_";
	tempoBox_->Size = System::Drawing::Size(416, 208);
	tempoBox_->TabIndex = 2;
	tempoBox_->TabStop = false;
	tempoBox_->Text = S"Set Tempo";
	
	// startMetronome
	startMetronomeButton_->Font = new System::Drawing::Font(S"Arial", 12, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, (System::Byte)0);
	startMetronomeButton_->Location = System::Drawing::Point(448, 368);
	startMetronomeButton_->Name = S"startMetronomeButton_";
	startMetronomeButton_->Size = System::Drawing::Size(75, 32);
	startMetronomeButton_->TabIndex = 9;
	startMetronomeButton_->Text = S"Start";
	startMetronomeButton_->Click += new System::EventHandler(this, startBeat);

	//add components to original app form
	form->Controls->Add(tempoBox_);
	form->Controls->Add(metBackButton_);
	form->Controls->Add(metronomeSettingsLabel_);
	form->Controls->Add(startMetronomeButton_);

	hideAll(); //hide all created components upon creation
	tempoBox_->ResumeLayout(false);
}

void MetronomeControl::hideAll()
{
	//hide each indiviudal metronome mode component
	metronomeSettingsLabel_->Hide();
	metBackButton_->Hide();
	tempoBox_->Hide();
	startMetronomeButton_->Hide();
}

void MetronomeControl::showAll()
{
	//show each individual metronome mode component
	metronomeSettingsLabel_->Show();
	metBackButton_->Show();
	tempoBox_->Show();
	startMetronomeButton_->Show();
}

void MetronomeControl::slowTempo(System::Object * sender, System::EventArgs * e)
{
	//do not go below threshold tempo of 20
	if( tempo_ > 20 )
	{
		tempo_-=2; //decrement by 2
		
		//create String to display tempo on app
		char tempoString[4];
		itoa(tempo_, tempoString, 10);
		tempoNumberLabel_->Text = new String(tempoString);
		
		//check for names for new tempo
		checkTempoName();
	}
}

void MetronomeControl::fastTempo(System::Object * sender, System::EventArgs * e)
{
	//do not go above threshold tempo of 220
	if( tempo_ < 220 )
	{
		tempo_+=2; //increment by 2
		
		//create String to display tempo on app
		char tempoString[4];
		itoa(tempo_, tempoString, 10);
		tempoNumberLabel_->Text = new String(tempoString);
		
		//check for names for new tempo
		checkTempoName();
	}
}

void MetronomeControl::checkTempoName()
{
	switch(tempo_)
	{
		//check tempo int for matching name
		case 120:
			tempoLabel_->Text = S"Allegro";
			break;
		case 200:
			tempoLabel_->Text = S"Presto";
			break;
		case 108:
			tempoLabel_->Text = S"Moderato";
			break;
		case 66:
			tempoLabel_->Text = S"Adagio";
			break;
		case 40:
			tempoLabel_->Text = S"Largo";
			break;
		case 140:
			tempoLabel_->Text = S"Vivace";
			break;
		case 76:
			tempoLabel_->Text = S"Andante";
		default:
			//default to no name
			tempoLabel_->Text = S"";
			break;
	}
}

void MetronomeControl::startBeat(System::Object * sender, System::EventArgs * e)
{
	//if the metronome is already running, stop it
	if(thread_ && thread_->IsAlive)
	{
		shouldRun_ = false;
		startMetronomeButton_->Text = S"Start"; //change "stop" text back to "start"
	}
	else //otherwise, metronome is not running, so start it
	{
		shouldRun_ = true; 
		startMetronomeButton_->Text = S"Stop"; //change "start" text to "stop"
		
		//create and start thread to play tempo
		ThreadStart *myThreadDelegate = new ThreadStart(this, playBeat);
		thread_ = new Thread(myThreadDelegate);
		thread_->IsBackground = true;
		thread_->Start();
	}

}

void MetronomeControl::loadMainMenu(System::Object * sender, System::EventArgs * e)
{
    hideAll(); //hide all metronome components
    
    //show the main menu components
	welcomeLabel_->Show();
	goToTunerButton_->Show();
	goToMetronomeButton_->Show();
}

//method for thread
void MetronomeControl::playBeat()
{
	//create an AudioSampler object to handle audio
	AudioSampler sampler;
	
	//while the metronome should still be running
	while(shouldRun_)
	{
		sampler.playTone(); //play the tone
		Thread::Sleep(60000/tempo_); //sleep for (1000 milliseconds/second) * (60 seconds/minute) / (tempo beats/minute)
	}
}